﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using ObjectTransposeApi;

namespace ObjectTransposeApiSystemTest.TestFixture
{
    [TestFixture]
    public class ToValueListFixture
    {
        public class NullStructure
        {
            public object Values
            {
                get { return null; }
                set { /* dso nothing */; }
            }
        }

        public class ValuesStructure
        {
            public List<object> Values { get; set; }
        }

        public class FirstChildStructure
        {
            public string Value { get; set; }
            public List<string> Values { get; set; }
        }

        public class SecondChildStructure
        {
            private SecondChildStructure() 
            {
            }
        }

        public class ParentStructure
        {
            public List<FirstChildStructure> FirstChildStructures { get; set; }
            public List<SecondChildStructure> SecondChildStructures { get; set; }
        }

        [Test]
        public void NullTest()
        {
            ValuesStructure valuesStructure = ObjectToValue.Copy<ValuesStructure>(new NullStructure());

            // make sure the field was set
            Assert.IsNotNull(valuesStructure.Values);
            Assert.AreEqual(valuesStructure.Values.Count, 0);
        }

        [Test]
        public void EmptyTest()
        {
            List<string> values = new List<string>();

            // build the output
            var groupedSources = values.GroupBy(value => value.Substring(0, 1), (key, value) => new
            {
                Value = key,
                Values = value
            });

            var sources = new
            {
                FirstChildStructures = groupedSources
            };

            ParentStructure parentStructure = ObjectToValue.Copy<ParentStructure>(sources);

            // make sure the field was set
            Assert.IsNotNull(parentStructure.FirstChildStructures);
            Assert.AreEqual(parentStructure.FirstChildStructures.Count,0);
        }

        [Test]
        public void NoConstructorEmptyTest()
        {
            List<string> values = new List<string>();

            // add values
            values.Add("apple");
            values.Add("banana");
            values.Add("grape");
            values.Add("mango");
            values.Add("mandarine");
            values.Add("pear");
            values.Add("peach");

            // build the output
            var groupedSources = values.GroupBy(value => value.Substring(0, 1), (key, value) => new
            {
                Value = key,
                Values = value
            });

            var sources = new
            {
                SecondChildStructures = groupedSources
            };

            ParentStructure parentStructure = ObjectToValue.Copy<ParentStructure>(sources);

            // make sure the field was set
            Assert.IsNotNull(parentStructure.SecondChildStructures);
            Assert.AreEqual(parentStructure.SecondChildStructures.Count, 0);
        }

        [Test]
        public void SuccessTest()
        {
            List<string> values = new List<string>();

            // add values
            values.Add("apple");
            values.Add("banana");
            values.Add("grape");
            values.Add("mango");
            values.Add("mandarine");
            values.Add("pear");
            values.Add("peach");

            // build the output
            var groupedSources = values.GroupBy(value => value.Substring(0, 1), (key, value) => new
            {
                Value = key,
                Values = value
            });

            var sources = new
            {
                FirstChildStructures = groupedSources
            };

            ParentStructure parentStructure = ObjectToValue.Copy<ParentStructure>(sources);

            // make sure the field was set
            Assert.AreEqual(parentStructure.FirstChildStructures.Count, 5);
            Assert.AreEqual(parentStructure.FirstChildStructures[0].Value, "a");
            Assert.AreEqual(parentStructure.FirstChildStructures[0].Values.Count, 1);
            Assert.AreEqual(parentStructure.FirstChildStructures[0].Values[0], "apple");
            Assert.AreEqual(parentStructure.FirstChildStructures[1].Value, "b");
            Assert.AreEqual(parentStructure.FirstChildStructures[1].Values.Count, 1);
            Assert.AreEqual(parentStructure.FirstChildStructures[1].Values[0], "banana");
            Assert.AreEqual(parentStructure.FirstChildStructures[2].Value, "g");
            Assert.AreEqual(parentStructure.FirstChildStructures[2].Values.Count, 1);
            Assert.AreEqual(parentStructure.FirstChildStructures[2].Values[0], "grape");
            Assert.AreEqual(parentStructure.FirstChildStructures[3].Value, "m");
            Assert.AreEqual(parentStructure.FirstChildStructures[3].Values.Count, 2);
            Assert.AreEqual(parentStructure.FirstChildStructures[3].Values[0], "mango");
            Assert.AreEqual(parentStructure.FirstChildStructures[3].Values[1], "mandarine");
            Assert.AreEqual(parentStructure.FirstChildStructures[4].Value, "p");
            Assert.AreEqual(parentStructure.FirstChildStructures[4].Values.Count, 2);
            Assert.AreEqual(parentStructure.FirstChildStructures[4].Values[0], "pear");
            Assert.AreEqual(parentStructure.FirstChildStructures[4].Values[1], "peach");
        }
    }
}
